package com.wzdigit.wms.wms.controller.stockIn;

import com.wzdigit.framework.Shift;
import com.wzdigit.framework.exception.RestStatusException;
import com.wzdigit.framework.model.response.ErrorEntity;
import com.wzdigit.wms.basic.domain.asn.AsnHeader;
import com.wzdigit.wms.basic.service.code.WhsPermService;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.asn.other.SearchOtherInOrderGoodsRequest;
import com.wzdigit.wms.basic.client.request.asn.other.SearchOtherInOrderRequest;
import com.wzdigit.wms.basic.client.request.asn.other.SearchOtherInSnRequest;
import com.wzdigit.wms.basic.client.request.asn.other.SubmitOtherInInputRequest;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.asn.other.OtherInOrderGoodsResponse;
import com.wzdigit.wms.basic.client.response.asn.other.OtherInOrderInfoResponse;
import com.wzdigit.wms.basic.client.response.asn.other.ScanOtherInOrderResponse;
import com.wzdigit.wms.basic.client.response.asn.other.ScanOtherInSnResponse;
import com.wzdigit.wms.basic.client.response.basic.WarehouseApiResponse;
import com.wzdigit.wms.wms.constant.WmsWareConstant;
import com.wzdigit.wms.wms.service.across.CallbackService;
import com.wzdigit.wms.wms.service.basic.WarehouseService;
import com.wzdigit.wms.wms.service.core.asn.AsnHeaderService;
import com.wzdigit.wms.wms.service.order.OtherStockInService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Api(tags = "其他入库")
@RequestMapping(value = WmsWareConstant.API_VERSION)
public class OtherStockInController {

    @Autowired
    private OtherStockInService otherStockInService;
    
    @Autowired
	private WhsPermService whsPremService;
    
    @Autowired
    private RedissonClient redisson;
    
    private final String REQUEST_MODEL = "/OtherStockIn";

    @ApiOperation(value = "获取其他入库任务（分页）", notes = "获取其他入库任务（分页）")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/search", method = RequestMethod.GET)
    public PagerInfo<List<OtherInOrderInfoResponse>> search(
            SearchOtherInOrderRequest input,
            HttpServletRequest servletRequest,
            HttpServletResponse servletResponse) {
        try {
            // 查询当前用户权限仓库
            List<WarehouseApiResponse> whList = whsPremService.getWarehousePerm(servletRequest);
            input.setRangeWhsIds(whList.stream().map(WarehouseApiResponse::getWhsId).distinct().collect(Collectors.toList()));
            return otherStockInService.search(input);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }


    /**
     * 扫描工单
     *
     * @return
     */
    @ApiOperation(value = "扫描单号", notes = "扫描单号")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/scanOrder", method = RequestMethod.GET)
    public Result<ScanOtherInOrderResponse> scanOrder(String billNo,
                                                      HttpServletRequest servletRequest,
                                                      HttpServletResponse servletResponse) {
        try {
            ScanOtherInOrderResponse ret = otherStockInService.scanOrder(billNo);
            return new Result<ScanOtherInOrderResponse>(true, "", ret);
        } catch (RestStatusException ex) {
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw ex;
        }
    }

    /**
     * 获取 sn 信息（分页）
     *
     * @param input
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    @ApiOperation(value = "获取 sn 信息（分页）", notes = "获取 sn 信息（分页）")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/searchOrderGoods", method = RequestMethod.GET)
    public PagerInfo<List<OtherInOrderGoodsResponse>> searchOrderGoods(SearchOtherInOrderGoodsRequest input,
                                                                       HttpServletRequest servletRequest,
                                                                       HttpServletResponse servletResponse) {
        try {
            return otherStockInService.searchOrderGoods(input);
        } catch (RestStatusException e) {
            e.printStackTrace();
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw e;
        }
    }

    /**
     * 扫描sn
     *
     * @return
     */
    @ApiOperation(value = "扫描SN", notes = "扫描SN")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/scanSn", method = RequestMethod.POST)
    public Result<ScanOtherInSnResponse> scanSn(
    		@RequestBody @Valid SearchOtherInSnRequest input,
    		HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
        try {
            return otherStockInService.scanSn(input);
        } catch (RestStatusException ex) {
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw ex;
        }
    }

    /**
     * 提交
     *
     * @return
     * @throws Exception 
     */
    @ApiOperation(value = "[其他入库]提交数据", notes = "[其他入库]提交数据")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/submit", method = RequestMethod.POST)
    public Result<Boolean> submit(@Valid @RequestBody SubmitOtherInInputRequest input,
                                  HttpServletRequest servletRequest,
                                  HttpServletResponse servletResponse) throws Exception {
        try {
            String userName = HttpSessionUtil.getLoginName(servletRequest);
            input.setUserName(userName);
            Boolean isClose = false;
            String key = "Key_Order_" + input.getAsnNo();
            RLock lock = redisson.getLock(key);
            try {
                boolean status = lock.tryLock();
                if (status) {
                    isClose = otherStockInService.submit(input);
                }
            } finally {
                // 当前线程获取到锁再释放锁
                if (lock != null && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
            return new Result<>(true, "操作成功！", isClose);
        } catch (RestStatusException ex) {
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw ex;
        }
    }

    /**
     * 提交
     *
     * @return
     */
    @ApiOperation(value = "强制关闭", notes = "强制关闭")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/close", method = RequestMethod.POST)
    public Result close(String billNo,
                        HttpServletRequest servletRequest,
                        HttpServletResponse servletResponse) {
        try {
            String userName = HttpSessionUtil.getLoginName(servletRequest);
            if ("".equals(billNo))
                Shift.fatal("请传入单据号!");
            String key = "Key_Order_" + billNo;
            RLock lock = redisson.getLock(key);
            try {
                boolean status = lock.tryLock();
                if (status) {
                	otherStockInService.close(billNo, userName);
                }
            } finally {
                // 当前线程获取到锁再释放锁
                if (lock != null && lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
            return new Result(true, "操作成功！");
        } catch (RestStatusException ex) {
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw ex;
        }
    }

    @Autowired
    AsnHeaderService asnHeaderService;
    @Autowired
    private CallbackService callbackService;

    /**
     * 提交
     *
     * @return
     */
    @ApiOperation(value = "写入SAP回传信息", notes = "写入SAP回传信息")
    @ApiResponses({@ApiResponse(code = 500, message = "系统出现异常", response = ErrorEntity.class)})
    @RequestMapping(value = REQUEST_MODEL + "/sapInfoWrite", method = RequestMethod.POST)
    public Result sapInfoWrite(String billNo,
                               HttpServletRequest servletRequest,
                               HttpServletResponse servletResponse) {
        try {
            AsnHeader asnHeader = asnHeaderService.selectByNo(billNo);
            this.callbackService.Callback(asnHeader);
            return new Result(true, "操作成功！");
        } catch (RestStatusException ex) {
            servletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            throw ex;
        }
    }
}

